#!/usr/bin/env python
# encoding = utf-8

import os
import sys
import struct

def has_id3v1(filename):
    flag = False
    f = open(filename, 'rb')
    try: f.seek(-128, 2)
    except IOError: pass
    else: flag = (f.read(3) == 'TAG')
    f.close()
    return flag

def get_id3v1(filename):
    id3v1 = None
    f = open(filename, 'rb')
    try: f.seek(-128, 2)
    except IOError: pass
    else: id3v1 = _parse_id3v1(f.read(128))
    return id3v1

def _parse_id3v1(raw_tag):
    tag = {}
    flag,tag['title'],tag['artist'],tag['album'],tag['year'],tag['comment'],tag['genre'] = struct.unpack('3s30s30s30s4s30s1c',raw_tag)
    return tag

def set_id3v1(filename, tag={}):
    tag_bytes = struct.pack('3s30s30s30s4s30s1c','TAG',tag['title'],tag['artist'],tag['album'],tag['year'],tag['comment'],tag['genre'])
    try:
        has_tag = has_id3v1(filename)
        try: f = open(filename, 'rb+')
        except IOError: raise
        if has_tag:
            f.seek(-128, 2)
        else:
            f.seek(0, 2)
        f.write(tag_bytes)
    finally:
        f.close()

def del_id3v1(filename):
    pass

def _encode(s):
    try:
        if isinstance(s, unicode):
            return s.encode('gb2312')
        else:
            return s.decode('utf-8').encode('gb2312')
    except:
        return 'encode error'

def update_mp3_tag_id3v1(filename, track_info):
    tag = {}
    tag['title'] = str(_encode(track_info['title']))
    tag['artist'] = str(_encode(track_info['artist']))
    tag['album'] = str(_encode(track_info['album_name']))
    tag['year'] = ''
    tag['comment'] = ''
    tag['genre'] = '0'
    set_id3v1(filename, tag)

if __name__ == '__main__':
    fn = 'Superstar.mp3'
    track_info = {}
    track_info['title'] = 'new title'
    track_info['artist'] = 'new artist'
    track_info['album_name'] = 'new new album name'
    print get_id3v1(fn)
    update_mp3_tag_id3v1(fn, track_info)
    print get_id3v1(fn)

